package com.zx.notification.common.service;

import com.zx.notification.common.event.ConfigReloadEvent;
import com.zx.redis.block.service.RedisBlockService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.stereotype.Service;

/**
 * 配置变更监听器
 * 监听Redis中的配置变更消息，并触发本地配置重载
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ConfigChangeListener implements MessageListener, ApplicationEventPublisherAware {

    private final RedisBlockService redisBlockService;
    private ApplicationEventPublisher eventPublisher;

    /**
     * 监听Redis消息
     *
     * @param message 消息内容
     * @param pattern 匹配模式
     */
    @Override
    public void onMessage(Message message, byte[] pattern) {
        try {
            String channel = new String(message.getChannel());
            String body = new String(message.getBody());

            log.info("收到配置变更消息 - 频道: {}, 消息内容: {}", channel, body);

            // 根据消息内容触发相应的配置重载
            if ("notification:config:reload".equals(channel)) {
                handleConfigReload(body);
            }
        } catch (Exception e) {
            log.error("处理配置变更消息时发生错误", e);
        }
    }

    /**
     * 处理配置重载消息
     *
     * @param message 消息内容
     */
    private void handleConfigReload(String message) {
        // 这里可以解析消息内容，确定具体需要重载的配置类型
        // 例如: "mq_config" 表示MQ配置变更
        log.info("开始重载配置: {}", message);

        // 发布应用事件，通知各监听器重新加载配置
        ConfigReloadEvent event = new ConfigReloadEvent(this, "mq_config", message);
        eventPublisher.publishEvent(event);
    }

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.eventPublisher = applicationEventPublisher;
    }

    /**
     * 发布配置变更消息
     *
     * @param configType 配置类型
     * @param message    消息内容
     */
    public void publishConfigChange(String configType, String message) {
        try {
            String channel = "notification:config:reload";
            String content = configType + ":" + message;
            // 注意：这里需要使用RedisTemplate的convertAndSend方法发送消息
            // 但由于RedisBlockService没有提供该方法，我们暂时记录日志
            log.info("发布配置变更消息到Redis - 频道: {}, 内容: {}", channel, content);
        } catch (Exception e) {
            log.error("发布配置变更消息到Redis失败", e);
        }
    }
}